import os.path
import shutil
from datetime import datetime
from pathlib import Path
from typing import List, Dict, Literal

import cv2
from fastapi import APIRouter, UploadFile, File, HTTPException, Depends, Query

from backend.config.settings import settings
from backend.model_core import DualFundusModel
from backend.models.detection_model import ImageUpload, DetectionResult, BatchDetectionResponse, \
    DetectionResponse, BatchDetectionRequest, DetectionRequest
from backend.utils.database import create_detection_record, get_detection_record_by_user
from backend.utils.permission import require_authenticated_user

router = APIRouter(
    prefix="/detection",
    tags=["detection"],
    responses={404: {"description": "Not Found"}},
)

# 检查上传目录
UPLOAD_DIR = Path(settings.MODEL_PATH).parent / "uploads"
if not UPLOAD_DIR.exists():
    UPLOAD_DIR.mkdir(parents=True)

# 游客专用接口
@router.post("/guest/predict", response_model=DetectionResponse)
async def guest_predict_disease(request: DetectionRequest):
    try:
        left_path = request.left_eye.image_path
        right_path = request.right_eye.image_path
        age = request.age
        sex = 1 if request.sex == "male" else 0
        # 检查图像是否存在
        for eye_image in [request.left_eye, request.right_eye]:
            if not os.path.exists(eye_image.image_path):
                raise HTTPException(status_code=404, detail=f"图像不存在:{eye_image.image_path}")

        model = DualFundusModel("../backend/model_core/model.pth")
        # 调用模型进行预测
        probabilities = model.predict(cv2.imread(left_path), cv2.imread(right_path), age, sex)

        # 根据概率生成检测结果
        prediction_result = {
            "正常": f"{probabilities[0]:.4f}",
            "糖尿病": f"{probabilities[1]:.4f}",
            "青光眼": f"{probabilities[2]:.4f}",
            "白内障": f"{probabilities[3]:.4f}",
            "AMD": f"{probabilities[4]:.4f}",
            "高血压": f"{probabilities[5]:.4f}",
            "近视": f"{probabilities[6]:.4f}",
            "其他疾病/异常 ": f"{probabilities[7]:.4f}",
        }

        result = DetectionResult(
            probabilities=prediction_result
        )

        return DetectionResponse(record_id=0, result=result)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"检测失败：{str(e)}")
# 依赖函数，验证eye_type
def validate_eye_type(eye_type: Literal["left", "right"] = Query(...)):
    return eye_type

# 复用上传逻辑
async def upload_image(file: UploadFile, eye_type: str):
    upload_path = UPLOAD_DIR / file.filename
    try :
        with upload_path.open("wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
        return {"image_path": str(upload_path),"eye_type":eye_type}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"图像上传失败：{str(e)}")

# 左眼上传接口
@router.post("/upload/left", response_model=ImageUpload)
async def upload_left_eye(file: UploadFile = File(...),eye_type: str = Depends(lambda: validate_eye_type("left"))):
    return await upload_image(file, eye_type)

# 右眼上传接口
@router.post("/upload/right", response_model=ImageUpload)
async def upload_right_eye(file: UploadFile = File(...),eye_type: str = Depends(lambda: validate_eye_type("right"))):
    return await upload_image(file, eye_type)

@router.post("/predict", response_model=DetectionResponse)
async def predict_disease(request: DetectionRequest, user: dict = Depends(require_authenticated_user)):
    # 预测眼部疾病，用户ID从JWT获取
    try :
        left_path = request.left_eye.image_path
        right_path = request.right_eye.image_path
        age = request.age
        sex = 1 if request.sex == "male" else 0
        # 检查图像是否存在
        for eye_image in [request.left_eye, request.right_eye]:
            if not os.path.exists(eye_image.image_path):
                raise HTTPException(status_code=404, detail=f"图像不存在:{eye_image.image_path}")

        model = DualFundusModel("backend/model_core/model.pth")
        # 调用模型进行预测
        probabilities = model.predict(cv2.imread(left_path), cv2.imread(right_path), age, sex)

        # 根据概率生成检测结果
        prediction_result = {
            "正常": f"{probabilities[0]:.4f}",
            "糖尿病": f"{probabilities[1]:.4f}",
            "青光眼": f"{probabilities[2]:.4f}",
            "白内障": f"{probabilities[3]:.4f}",
            "AMD": f"{probabilities[4]:.4f}",
            "高血压": f"{probabilities[5]:.4f}",
            "近视": f"{probabilities[6]:.4f}",
            "其他疾病/异常 ": f"{probabilities[7]:.4f}",
        }


        result = DetectionResult(
            probabilities=prediction_result
        )


        user_id = user["user_id"]
        record_id = create_detection_record(
                user_id,
                left_path,
                right_path,
                prediction_result,
                request.sex,
                request.age
            )

        return DetectionResponse(
            record_id=record_id,
            result=result
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"检测失败：{str(e)}")


# # 批量预测眼部疾病
# @router.post("/batch_predict", response_model=BatchDetectionResponse)
# async def batch_predict_disease(batch_request: BatchDetectionRequest):
#     results = []
#     for path in batch_request.image_paths:
#         image_path = str(path)
#         # 如果文件不存在跳过
#         if not os.path.exists(image_path):
#             continue
#         try:
#             # 还没写模型，先返回模拟结果
#             prediction_result = {
#                 "disease_prediction": "正常" if "normal" in image_path else "青光眼",
#                 "confidence":0.95,
#                 "details":{"probabilities":{"正常":0.95,"青光眼":0.05}}
#             }
#             # 创建检测记录
#             record_id = create_detection_record(
#                 user_id=batch_request.user_id,
#                 left_image_path=image_path,
#                 right_image_path=image_path,
#                 prediction=prediction_result
#             )
#             results.append({
#                 "record_id": record_id,
#                 "image_path":image_path,
#                 "result": prediction_result,
#                 "created_at":datetime.now()
#                 })
#         except Exception as e:
#             print(f"批量预测中检测{image_path}时出错：{str(e)}")
#     if not results:
#         raise HTTPException(status_code=404, detail="没有有效的检测结果")
#     return BatchDetectionResponse(records=results)

#获取用户的检测记录
@router.get("/user_records", response_model=List[Dict])
async def get_user_detection_records(current_user: dict = Depends(require_authenticated_user)):
    user_id = current_user["user_id"]
    try:
        records = get_detection_record_by_user(user_id)
        if not records:
            return []
        return records
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取用户检测记录失败：{str(e)}")